
#ifdef IMAM_COMMS
#include "SDK30.H"
#include "linklayer.h"
#include <Param.h>
#include <schvar_Def.h>
//#include <definekey.h>
#include <fm_proto.h>
#include <fm_hmiservice.h>
#include <fm_genpinpad.h>
#include <fm_userinterface.h>
#include <fm_comms.h> 

#include <SSL_.h>
#include <X509_.h>
#include <cmm_ssl.h>

extern uint8 pp_get_key(uint32 timeout);
//void _trace4(const char * format,...);

#define Alarm(x) pp_beep(x)

#else
#include <incs.h>
#endif

#ifdef IMAM_COMMS

#define PROFILE_NAME			"PROFILE_00"
#define CLIENT_KEY 				"/SYSTEM/CLIENT_KEY.PEM"
#define CLIENT_CERTIFICATE		"/SYSTEM/CLIENT.CRT"
#define CA_CERTIFICATE			"/SYSTEM/CA.CRT"

#define CONNECT_TIMEOUT		1000
#define SEND_TIMEOUT			1000
#define RECEIVE_TIMEOUT		1000


static SSL_HANDLE SslHandle;				// ssl handle
static SSL_PROFILE_HANDLE ProfileHandle;	// profile handle
static char SslHostName[50];				// host ip or name
static int SslPort;							// port
static int8 Connecting;						// flag for indicating that connecting is in progress


void SslPrintProfile( SSL_PROFILE_HANDLE profileHandle);





int8 SslSetProfile()
{
	// Delete profile if exist
	SSL_DeleteProfile(PROFILE_NAME);

	// Create new one
	ProfileHandle = SSL_NewProfile(PROFILE_NAME, NULL);

	if(ProfileHandle == NULL)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "CREATE NEW PROFILE", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return 0;
	}

	// Set protocol
	SSL_ProfileSetProtocol(ProfileHandle, SSLv3 );

	// Set Chiper
	SSL_ProfileSetCipher(ProfileHandle, 
						SSL_RSA | SSL_DES| SSL_3DES | SSL_RC4 | SSL_RC2 | SSL_MAC_MASK | SSL_SSLV3,
						SSL_HIGH | SSL_NOT_EXP );

	// Certificate and keys
	SSL_ProfileSetKeyFile(ProfileHandle, CLIENT_KEY, FALSE );
	SSL_ProfileSetCertificateFile(ProfileHandle, CLIENT_CERTIFICATE );
	SSL_ProfileAddCertificateCA(ProfileHandle, CA_CERTIFICATE);

	// Save profile
	SSL_SaveProfile(ProfileHandle);

	// Print profile
	//SslPrintProfile(ProfileHandle);

	// Unload
	SSL_UnloadProfile(ProfileHandle);

	ProfileHandle = NULL;

	pp_display_clear(0);//enfi 09082010-2
	pp_display_text(2, 0, "CREATE NEW PROFILE", PT_ALIGN_CENTER);//enfi 09082010-2
	pp_display_text(3, 0, "SUCCESS", PT_ALIGN_CENTER);//enfi 09082010-2
	pp_get_key(2);

	return 1;
}

void PrintSSLProfile(void)
{
	ProfileHandle = SSL_LoadProfile(PROFILE_NAME);
	
	if(ProfileHandle == NULL)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "LOAD SSL PROFILE", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return ;
	}

	SslPrintProfile(ProfileHandle);
	
	if(ProfileHandle != NULL)
	{
		SSL_UnloadProfile(ProfileHandle);
		ProfileHandle = NULL;
	}
		


	
}
void SslSetConnectingFlag(int8 flag)
{
	Connecting = flag;
}

int8 SslIsConnecting()
{
	return Connecting;
}

int16 SslGetLastError()
{
	int16 Error;

	if(ProfileHandle != NULL)
		SSL_ProfileGetLastError(ProfileHandle, (int*)&Error);
	else
		Error = 0;

	return Error;
}

void SslConfigureHost(char * hostName, int port)
{
	memset(SslHostName, 0x00, sizeof(SslHostName));
	strcpy(SslHostName, hostName);
	SslPort = port;
//	_trace4("SslConfigureHost> SSL_HostName : %s, SSL_Port : %d", SslHostName, SslPort);
}

int8 SslConnect()
{
	// Load profile
	ProfileHandle = SSL_LoadProfile(PROFILE_NAME);

	if(ProfileHandle == NULL)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "LOAD SSL PROFILE", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return 0;
	}
//	_trace4("SslConnect> SSL Profile : %d", ProfileHandle);
	// Create SSL
	if(SSL_New(&SslHandle, ProfileHandle) != 0)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "CREATE NEW", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "SSL CONNECTION", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(4, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return 0;
	}

	// Get connected
//	_trace4("SslConnect> SSL_HostName : %s, SSL_Port : %d", SslHostName, SslPort);
//	_trace4("SslConnect> SSL Profile : %d, SSL handle : %d", ProfileHandle, SslHandle);
	if(SSL_Connect(SslHandle, SslHostName, SslPort, CONNECT_TIMEOUT*10) != 0)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "SSL GET CONNECTED", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return 0;
	}
	return 1;	
}

void SslDisconnect()
{
	if(ProfileHandle != NULL)
	{
		SSL_UnloadProfile(ProfileHandle);
		ProfileHandle = NULL;
	}
		

	if(SslHandle != NULL)
	{
		// Disconnect
		SSL_Disconnect(SslHandle);

		// Free resource
		SSL_Free(SslHandle);

		SslHandle = NULL;
	}
}

int SslSend(const void * buffer, int buffLen)
{
	int NumSend;

	if(SslHandle == NULL)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "SSL SEND DATA", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return -1;
	}
//	_trace4("SslSend> SSL Profile : %d, SSL handle : %d", ProfileHandle, SslHandle);
	NumSend = SSL_Write(SslHandle, buffer, buffLen, SEND_TIMEOUT*10);

	return NumSend;
}

int SslReceive(void * buffer, int buffLen)
{
	int NumReceive;

	if(SslHandle == NULL)
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "SSL RECEIVE DATA", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return -1;
	}
//	_trace4("SslReceive> SSL Profile : %d, SSL handle : %d", ProfileHandle, SslHandle);
	NumReceive = SSL_Read(SslHandle, buffer, buffLen, RECEIVE_TIMEOUT*200);//enfi "100->200" 09082010

//	_trace("SSL Read return value : %i", NumReceive);

	return NumReceive;
}


void SslPrintProfile( SSL_PROFILE_HANDLE profileHandle)
{
	int i;
	X509_HANDLE CertHandle;

	char szTmp[80];
	int szTmpSize = 80;
	
	if( profileHandle == NULL )
	{
		pp_display_clear(0);//enfi 09082010-2
		pp_display_text(2, 0, "SSL PRINT PROFILE", PT_ALIGN_CENTER);//enfi 09082010-2
		pp_display_text(3, 0, "FAILED", PT_ALIGN_CENTER);//enfi 09082010-2
		Alarm(ALARM_ERROR);
		pp_get_key(3);
		return;
	}

	if( SSL_ProfileGetName( profileHandle, szTmp ) == 0 )
		xx_pprintf("%s\n\n", szTmp);

	if( SSL_ProfileGetCertificateFile( profileHandle, szTmp ) == 0 )
	{
		xx_pprintf("Client Certificate :\n");

		if(( CertHandle = X509_Load( szTmp )) != NULL )
		{
			if(X509_GetInfo(CertHandle, X509_NOTBEFORE, 0, szTmp, szTmpSize) >0 )
				xx_pprintf("Not Before : %s\n", szTmp);
			
			if(X509_GetInfo(CertHandle, X509_NOTAFTER,0,szTmp,szTmpSize)>0)
				xx_pprintf("Not After : %s\n\n", szTmp);
			
			X509_Unload( CertHandle );
		}
	}
	
	i = 0;
	while(SSL_ProfileGetCAFile( profileHandle, i, szTmp ) == 0)
	{
		xx_pprintf("Certificate Authority :\n");

		if(( CertHandle = X509_Load( szTmp )) != NULL )
		{
			if(X509_GetInfo(CertHandle, X509_NOTBEFORE, 0, szTmp, szTmpSize) > 0)
				xx_pprintf("Not Before : %s\n", szTmp);
							
			if(X509_GetInfo(CertHandle, X509_NOTAFTER, 0, szTmp, szTmpSize) > 0)
				xx_pprintf("Not After : %s\n", szTmp);
			
			if(X509_GetInfo(CertHandle, X509_ISSUER, NID_commonName, szTmp, szTmpSize) > 0)
				xx_pprintf("Issuer %s :\n%s\n\n", SN_commonName, szTmp);
			
			X509_Unload( CertHandle);
		}
		
		i++;
	}
	
	xx_pprintf("\n\n\n\n\n\n");
	ttestall(0, 50);
}

/*
void trace4_SSL(void)
{
	_trace4("lokal SSL Profile : %d, SSL handle : %d", ProfileHandle, SslHandle);
}
*/

#endif


